package com.zzyl.serve.service.impl;

import java.time.LocalDateTime;
import java.util.*;

import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.bean.BeanUtils;
import com.zzyl.serve.domain.*;
import com.zzyl.serve.dto.*;
import com.zzyl.serve.mapper.*;
import com.zzyl.serve.util.CodeGenerator;
import com.zzyl.serve.vo.CheckInConfigVo;
import com.zzyl.serve.vo.CheckInDetailVo;
import com.zzyl.serve.vo.CheckInElderVo;
import com.zzyl.serve.vo.ElderFamilyVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration;
import org.springframework.stereotype.Service;
import com.zzyl.serve.service.ICheckInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

/**
 * 入住Service业务层处理
 *
 * @author liufan
 * @date 2025-08-15
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService {
    @Autowired
    private CheckInMapper checkInMapper;
    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private ObjectPostProcessorConfiguration objectPostProcessorConfiguration;
    @Autowired
    private BedMapper bedMapper;
    @Autowired
    private CheckInConfigMapper checkInConfigMapper;
    @Autowired
    private ContractMapper contractMapper;

    /**
     * 查询入住
     *
     * @param id 入住主键
     * @return 入住
     */
    @Override
    public CheckIn selectCheckInById(Long id) {
        return checkInMapper.selectById(id);
    }

    /**
     * 查询入住列表
     *
     * @param checkIn 入住
     * @return 入住
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn) {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn) {
        return checkInMapper.insert(checkIn);
    }

    /**
     * 修改入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn) {
        return checkInMapper.updateById(checkIn);
    }

    /**
     * 批量删除入住
     *
     * @param ids 需要删除的入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids) {
        return checkInMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除入住信息
     *
     * @param id 入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id) {
        return checkInMapper.deleteById(id);
    }

    @Override
    public void apply(CheckInApplyDto dto) {
        //1. 如果老人已经入住（老人身份证号已存在，且状态为1），则抛异常
        Elder elder = new Elder();

        if (elderMapper.selectByIdCardNo(elder.getIdCardNo()) != null
                && Objects.equals(elderMapper.selectByIdCardNo(elder.getIdCardNo()).getStatus(), 1)) {
            throw new BaseException("老人已入住");
        }
        Bed bed = bedMapper.selectById(dto.getCheckInConfigDto().getBedId());//把找到的床保存到bed
        if (Objects.equals(bed.getBedStatus(), 1)) { //如果这个床的状态为1则表示已被入住
            throw new BaseException("床位已入住");
        }
        bed.setBedStatus(1);//如果没有人入住，现在开始办理入住
        bedMapper.updateBed(bed);


        //3. 保存老人信息
        //  将dto中老人的信息封装成Elder对象
        BeanUtils.copyProperties(dto.getCheckInElderDto(), elder);
        elder.setStatus(1);
        //elder.setBedId(bed.getId());
        elder.setBedNumber(bed.getBedNumber());

        List<ElderFamilyDto> elderFamilyDtoList = dto.getElderFamilyDtoList();
        //使用工具类将familyDtoList转换成json格式的字符串保存到Remark里
        elder.setRemark(JSONUtil.toJsonStr(elderFamilyDtoList));
        if (elderMapper.selectByIdCardNo(elder.getIdCardNo()) == null) {
            elderMapper.insertElder(elder);
        } else {
            elder.setId(elderMapper.selectByIdCardNo(elder.getIdCardNo()).getId());
            elderMapper.updateById(elder);
        }
        //新增入住信息--6.3新增入住信息

        CheckInConfig checkInConfig = new CheckInConfig();
        CheckInConfigDto checkInConfigDto = dto.getCheckInConfigDto();

        CheckIn checkIn = new CheckIn();
        checkIn.setElderName(elder.getName());
        checkIn.setElderId(elder.getId());
        checkIn.setIdCardNo(elder.getIdCardNo());
        checkIn.setStartDate(dto.getCheckInConfigDto().getStartDate());
        checkIn.setEndDate(dto.getCheckInConfigDto().getEndDate());
        checkIn.setNursingLevelName(dto.getCheckInConfigDto().getNursingLevelName());
        checkIn.setBedNumber(elder.getBedNumber());
        checkIn.setStatus(0);
        checkInMapper.insert(checkIn);
        //save(checkIn);

        //新增配置信息
        BeanUtils.copyProperties(checkInConfigDto, checkInConfig);
        checkInConfig.setCheckInId(checkIn.getId());
        checkInConfigMapper.insert(checkInConfig);

        //新增合同信息
        Contract contract = new Contract();
        /**
         * "agreementPath": "https://itheim.oss-cn-beijing.aliyuncs.com/72731f06-d7d3-41ca-9343-b9422993ebda.png",
         *     "contractName": "刘天龙",
         *     "signDate": "2024-08-26 15:47:39",
         *     "thirdPartyName": "刘天",
         *     "thirdPartyPhone": "15543234568"
         */
        CheckInContractDto checkInContractDto = dto.getCheckInContractDto();
        BeanUtils.copyProperties(checkInContractDto, contract);
        contract.setElderId(elder.getId());
        contract.setElderName(elder.getName());
        contract.setContractNumber("HT" + CodeGenerator.generateContractNumber());
        contract.setStartDate(checkInConfigDto.getStartDate());
        contract.setEndDate(checkInConfigDto.getEndDate());
        //  如果当前时间 不早于合同开始时间，且不晚于合同结束时间，说明在合同有效期内
        LocalDateTime now = LocalDateTime.now();
        boolean b = !now.isBefore(contract.getStartDate()) && !now.isAfter(contract.getStartDate());
        contract.setStatus(b ? 1 : 0);
        //contract.setCreateTime(LocalDateTime.now());
        contractMapper.insert(contract);
    }

    @Override
    public CheckInDetailVo detail(Long id) {

        //创建接收查询结果的对象
        CheckInDetailVo checkInDetailVo = new CheckInDetailVo();
        //先通过入住表id(绑定了check_in表的id)找到check_in表的对象
        CheckIn findId = checkInMapper.selectCheckInById(id);
        //判断
        if (findId == null ) {
            throw new BaseException("没有入住信息");
        }
        //通过findId获取里面的elderId
        id = findId.getElderId();//Long elderId = findId.getElderId();
        //通过elderId查到老人信息
        Elder elder = elderMapper.detail(id);
        //创建接收老人信息的对象
        CheckInElderVo checkInElderVo = new CheckInElderVo();
        if (elder == null) {
            throw new BaseException("没有老人信息");
        }
        //保存老人信息到实例对象
        if (elder != null ){
            BeanUtils.copyProperties(elder,checkInElderVo);
            checkInDetailVo.setCheckInElderVo(checkInElderVo);
        }
        //创建接收老人家属信息的对象
        List<ElderFamilyVo> familyVos = new ArrayList<>();
        if (elder != null){
            String remark = elder.getRemark();

            if (remark != null && remark.trim().startsWith("[")) {
                try {
                    ObjectMapper objectMapper = new ObjectMapper();
                    List<Map<String, String>> list = objectMapper.readValue(remark, List.class);

                    ElderFamilyVo familyVo = new ElderFamilyVo();
                    familyVo.setName(list.get(0).get("name"));
                    familyVo.setPhone(list.get(0).get("phone"));
                    familyVo.setKinship(list.get(0).get("kinship"));

                    if (familyVo.getName() != null) {
                        familyVos.add(familyVo);
                    }
                } catch (Exception e) {
                    // 捕获所有 JSON 解析异常，避免程序崩溃
                    log.warn("解析 remark 失败: " + remark, e);
                }
            }
            //从老人信息里获取家属信息保存到家属信息对象。使用上面的方法转换
           // BeanUtils.copyProperties(remark,familyVos);
        }
        //保存家属信息对象到接受结果的对象
        checkInDetailVo.setElderFamilyVoList(familyVos);

        //通过check_in的id(关联了check_in_id)查找对应的checkInConfig对象
        CheckInConfig checkInConfig = checkInConfigMapper.selectCheckInConfigById(findId.getId());
        //创建保存checkInConfig信息的对象
        CheckInConfigVo checkInConfigVo = new CheckInConfigVo();
        if (checkInConfig != null) {
            //从checkInConfig信息里获取配置信息保存到配置信息对象
            BeanUtils.copyProperties(checkInConfig, checkInConfigVo);
            //保存配置信息对象到接受结果的对象
            checkInDetailVo.setCheckInConfigVo(checkInConfigVo);
        } else {
            //checkInConfig为null，保存到Vo避免异常
            checkInDetailVo.setCheckInConfigVo(null);
        }
        Contract contract = contractMapper.selectContractById(id);
        if (contract != null) {
            checkInDetailVo.setContract(contract);
        }
        return checkInDetailVo;
    }
}
